package com.fr.base.core.antlr;

import com.fr.base.core.antlr.collections.Stack;
import com.fr.base.core.antlr.collections.impl.LList;
import com.fr.base.core.antlr.collections.impl.Vector;

public class MakeGrammar extends DefineGrammarSymbols
{
  protected Stack blocks = new LList();
  protected RuleRefElement lastRuleRef;
  protected RuleEndElement ruleEnd;
  protected RuleBlock ruleBlock;
  protected int nested = 0;
  protected boolean grammarError = false;
  ExceptionSpec currentExceptionSpec = null;

  public MakeGrammar(Tool paramTool, String[] paramArrayOfString, LLkAnalyzer paramLLkAnalyzer)
  {
    super(paramTool, paramArrayOfString, paramLLkAnalyzer);
  }

  public void abortGrammar()
  {
    String str = "unknown grammar";
    if (this.grammar != null)
      str = this.grammar.getClassName();
    this.tool.error("aborting grammar '" + str + "' due to errors");
    super.abortGrammar();
  }

  protected void addElementToCurrentAlt(AlternativeElement paramAlternativeElement)
  {
    paramAlternativeElement.enclosingRuleName = this.ruleBlock.ruleName;
    context().addAlternativeElement(paramAlternativeElement);
  }

  public void beginAlt(boolean paramBoolean)
  {
    super.beginAlt(paramBoolean);
    Alternative localAlternative = new Alternative();
    localAlternative.setAutoGen(paramBoolean);
    context().block.addAlternative(localAlternative);
  }

  public void beginChildList()
  {
    super.beginChildList();
    context().block.addAlternative(new Alternative());
  }

  public void beginExceptionGroup()
  {
    super.beginExceptionGroup();
    if (!(context().block instanceof RuleBlock))
      this.tool.panic("beginExceptionGroup called outside of rule block");
  }

  public void beginExceptionSpec(Token paramToken)
  {
    if (paramToken != null)
      paramToken.setText(StringUtils.stripFront(StringUtils.stripBack(paramToken.getText(), " \n\r\t"), " \n\r\t"));
    super.beginExceptionSpec(paramToken);
    this.currentExceptionSpec = new ExceptionSpec(paramToken);
  }

  public void beginSubRule(Token paramToken1, Token paramToken2, boolean paramBoolean)
  {
    super.beginSubRule(paramToken1, paramToken2, paramBoolean);
    this.blocks.push(new BlockContext());
    context().block = new AlternativeBlock(this.grammar, paramToken2, paramBoolean);
    context().altNum = 0;
    this.nested += 1;
    context().blockEnd = new BlockEndElement(this.grammar);
    context().blockEnd.block = context().block;
    labelElement(context().block, paramToken1);
  }

  public void beginTree(Token paramToken)
    throws SemanticException
  {
    if (!(this.grammar instanceof TreeWalkerGrammar))
    {
      this.tool.error("Trees only allowed in TreeParser", this.grammar.getFilename(), paramToken.getLine(), paramToken.getColumn());
      throw new SemanticException("Trees only allowed in TreeParser");
    }
    super.beginTree(paramToken);
    this.blocks.push(new TreeBlockContext());
    context().block = new TreeElement(this.grammar, paramToken);
    context().altNum = 0;
  }

  public BlockContext context()
  {
    if (this.blocks.height() == 0)
      return null;
    return ((BlockContext)this.blocks.top());
  }

  public static RuleBlock createNextTokenRule(Grammar paramGrammar, Vector paramVector, String paramString)
  {
    RuleBlock localRuleBlock1 = new RuleBlock(paramGrammar, paramString);
    localRuleBlock1.setDefaultErrorHandler(paramGrammar.getDefaultErrorHandler());
    RuleEndElement localRuleEndElement = new RuleEndElement(paramGrammar);
    localRuleBlock1.setEndElement(localRuleEndElement);
    localRuleEndElement.block = localRuleBlock1;
    for (int i = 0; i < paramVector.size(); ++i)
    {
      RuleSymbol localRuleSymbol = (RuleSymbol)paramVector.elementAt(i);
      if (!(localRuleSymbol.isDefined()))
      {
        paramGrammar.antlrTool.error("Lexer rule " + localRuleSymbol.id.substring(1) + " is not defined");
      }
      else if (localRuleSymbol.access.equals("public"))
      {
        Alternative localAlternative = new Alternative();
        RuleBlock localRuleBlock2 = localRuleSymbol.getBlock();
        Vector localVector = localRuleBlock2.getAlternatives();
        if ((localVector != null) && (localVector.size() == 1))
        {
          localObject = (Alternative)localVector.elementAt(0);
          if (((Alternative)localObject).semPred != null)
            localAlternative.semPred = ((Alternative)localObject).semPred;
        }
        Object localObject = new RuleRefElement(paramGrammar, new CommonToken(41, localRuleSymbol.getId()), 1);
        ((RuleRefElement)localObject).setLabel("theRetToken");
        ((RuleRefElement)localObject).enclosingRuleName = "nextToken";
        ((RuleRefElement)localObject).next = localRuleEndElement;
        localAlternative.addElement((AlternativeElement)localObject);
        localAlternative.setAutoGen(true);
        localRuleBlock1.addAlternative(localAlternative);
        localRuleSymbol.addReference((RuleRefElement)localObject);
      }
    }
    localRuleBlock1.setAutoGen(true);
    localRuleBlock1.prepareForAnalysis();
    return ((RuleBlock)localRuleBlock1);
  }

  private AlternativeBlock createOptionalRuleRef(String paramString, Token paramToken)
  {
    AlternativeBlock localAlternativeBlock = new AlternativeBlock(this.grammar, paramToken, false);
    String str = CodeGenerator.encodeLexerRuleName(paramString);
    if (!(this.grammar.isDefined(str)))
      this.grammar.define(new RuleSymbol(str));
    CommonToken localCommonToken = new CommonToken(24, paramString);
    localCommonToken.setLine(paramToken.getLine());
    localCommonToken.setLine(paramToken.getColumn());
    RuleRefElement localRuleRefElement = new RuleRefElement(this.grammar, localCommonToken, 1);
    localRuleRefElement.enclosingRuleName = this.ruleBlock.ruleName;
    BlockEndElement localBlockEndElement = new BlockEndElement(this.grammar);
    localBlockEndElement.block = localAlternativeBlock;
    Alternative localAlternative1 = new Alternative(localRuleRefElement);
    localAlternative1.addElement(localBlockEndElement);
    localAlternativeBlock.addAlternative(localAlternative1);
    Alternative localAlternative2 = new Alternative();
    localAlternative2.addElement(localBlockEndElement);
    localAlternativeBlock.addAlternative(localAlternative2);
    localAlternativeBlock.prepareForAnalysis();
    return localAlternativeBlock;
  }

  public void defineRuleName(Token paramToken, String paramString1, boolean paramBoolean, String paramString2)
    throws SemanticException
  {
    if (paramToken.type == 24)
    {
      if (!(this.grammar instanceof LexerGrammar))
      {
        this.tool.error("Lexical rule " + paramToken.getText() + " defined outside of lexer", this.grammar.getFilename(), paramToken.getLine(), paramToken.getColumn());
        paramToken.setText(paramToken.getText().toLowerCase());
      }
    }
    else if (this.grammar instanceof LexerGrammar)
    {
      this.tool.error("Lexical rule names must be upper case, '" + paramToken.getText() + "' is not", this.grammar.getFilename(), paramToken.getLine(), paramToken.getColumn());
      paramToken.setText(paramToken.getText().toUpperCase());
    }
    super.defineRuleName(paramToken, paramString1, paramBoolean, paramString2);
    String str = paramToken.getText();
    if (paramToken.type == 24)
      str = CodeGenerator.encodeLexerRuleName(str);
    RuleSymbol localRuleSymbol = (RuleSymbol)this.grammar.getSymbol(str);
    RuleBlock localRuleBlock = new RuleBlock(this.grammar, paramToken.getText(), paramToken.getLine(), paramBoolean);
    localRuleBlock.setDefaultErrorHandler(this.grammar.getDefaultErrorHandler());
    this.ruleBlock = localRuleBlock;
    this.blocks.push(new BlockContext());
    context().block = localRuleBlock;
    localRuleSymbol.setBlock(localRuleBlock);
    this.ruleEnd = new RuleEndElement(this.grammar);
    localRuleBlock.setEndElement(this.ruleEnd);
    this.nested = 0;
  }

  public void endAlt()
  {
    super.endAlt();
    if (this.nested == 0)
      addElementToCurrentAlt(this.ruleEnd);
    else
      addElementToCurrentAlt(context().blockEnd);
    context().altNum += 1;
  }

  public void endChildList()
  {
    super.endChildList();
    BlockEndElement localBlockEndElement = new BlockEndElement(this.grammar);
    localBlockEndElement.block = context().block;
    addElementToCurrentAlt(localBlockEndElement);
  }

  public void endExceptionGroup()
  {
    super.endExceptionGroup();
  }

  public void endExceptionSpec()
  {
    super.endExceptionSpec();
    if (this.currentExceptionSpec == null)
      this.tool.panic("exception processing internal error -- no active exception spec");
    if (context().block instanceof RuleBlock)
      ((RuleBlock)context().block).addExceptionSpec(this.currentExceptionSpec);
    else if (context().currentAlt().exceptionSpec != null)
      this.tool.error("Alternative already has an exception specification", this.grammar.getFilename(), context().block.getLine(), context().block.getColumn());
    else
      context().currentAlt().exceptionSpec = this.currentExceptionSpec;
    this.currentExceptionSpec = null;
  }

  public void endGrammar()
  {
    if (this.grammarError)
      abortGrammar();
    else
      super.endGrammar();
  }

  public void endRule(String paramString)
  {
    super.endRule(paramString);
    BlockContext localBlockContext = (BlockContext)this.blocks.pop();
    this.ruleEnd.block = localBlockContext.block;
    this.ruleEnd.block.prepareForAnalysis();
  }

  public void endSubRule()
  {
    Object localObject;
    super.endSubRule();
    this.nested -= 1;
    BlockContext localBlockContext = (BlockContext)this.blocks.pop();
    AlternativeBlock localAlternativeBlock = localBlockContext.block;
    if ((localAlternativeBlock.not) && (!(localAlternativeBlock instanceof SynPredBlock)) && (!(localAlternativeBlock instanceof ZeroOrMoreBlock)) && (!(localAlternativeBlock instanceof OneOrMoreBlock)) && (!(this.analyzer.subruleCanBeInverted(localAlternativeBlock, this.grammar instanceof LexerGrammar))))
    {
      localObject = System.getProperty("line.separator");
      this.tool.error("This subrule cannot be inverted.  Only subrules of the form:" + ((String)localObject) + "    (T1|T2|T3...) or" + ((String)localObject) + "    ('c1'|'c2'|'c3'...)" + ((String)localObject) + "may be inverted (ranges are also allowed).", this.grammar.getFilename(), localAlternativeBlock.getLine(), localAlternativeBlock.getColumn());
    }
    if (localAlternativeBlock instanceof SynPredBlock)
    {
      localObject = (SynPredBlock)localAlternativeBlock;
      context().block.hasASynPred = true;
      context().currentAlt().synPred = ((SynPredBlock)localObject);
      this.grammar.hasSyntacticPredicate = true;
      ((SynPredBlock)localObject).removeTrackingOfRuleRefs(this.grammar);
    }
    else
    {
      addElementToCurrentAlt(localAlternativeBlock);
    }
    localBlockContext.blockEnd.block.prepareForAnalysis();
  }

  public void endTree()
  {
    super.endTree();
    BlockContext localBlockContext = (BlockContext)this.blocks.pop();
    addElementToCurrentAlt(localBlockContext.block);
  }

  public void hasError()
  {
    this.grammarError = true;
  }

  private void labelElement(AlternativeElement paramAlternativeElement, Token paramToken)
  {
    if (paramToken != null)
    {
      for (int i = 0; i < this.ruleBlock.labeledElements.size(); ++i)
      {
        AlternativeElement localAlternativeElement = (AlternativeElement)this.ruleBlock.labeledElements.elementAt(i);
        String str = localAlternativeElement.getLabel();
        if ((str != null) && (str.equals(paramToken.getText())))
        {
          this.tool.error("Label '" + paramToken.getText() + "' has already been defined", this.grammar.getFilename(), paramToken.getLine(), paramToken.getColumn());
          return;
        }
      }
      paramAlternativeElement.setLabel(paramToken.getText());
      this.ruleBlock.labeledElements.appendElement(paramAlternativeElement);
    }
  }

  public void noAutoGenSubRule()
  {
    context().block.setAutoGen(false);
  }

  public void oneOrMoreSubRule()
  {
    if (context().block.not)
      this.tool.error("'~' cannot be applied to (...)* subrule", this.grammar.getFilename(), context().block.getLine(), context().block.getColumn());
    OneOrMoreBlock localOneOrMoreBlock = new OneOrMoreBlock(this.grammar);
    setBlock(localOneOrMoreBlock, context().block);
    BlockContext localBlockContext = (BlockContext)this.blocks.pop();
    this.blocks.push(new BlockContext());
    context().block = localOneOrMoreBlock;
    context().blockEnd = localBlockContext.blockEnd;
    context().blockEnd.block = localOneOrMoreBlock;
  }

  public void optionalSubRule()
  {
    if (context().block.not)
      this.tool.error("'~' cannot be applied to (...)? subrule", this.grammar.getFilename(), context().block.getLine(), context().block.getColumn());
    beginAlt(false);
    endAlt();
  }

  public void refAction(Token paramToken)
  {
    super.refAction(paramToken);
    context().block.hasAnAction = true;
    addElementToCurrentAlt(new ActionElement(this.grammar, paramToken));
  }

  public void setUserExceptions(String paramString)
  {
    ((RuleBlock)context().block).throwsSpec = paramString;
  }

  public void refArgAction(Token paramToken)
  {
    ((RuleBlock)context().block).argAction = paramToken.getText();
  }

  public void refCharLiteral(Token paramToken1, Token paramToken2, boolean paramBoolean1, int paramInt, boolean paramBoolean2)
  {
    if (!(this.grammar instanceof LexerGrammar))
    {
      this.tool.error("Character literal only valid in lexer", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
      return;
    }
    super.refCharLiteral(paramToken1, paramToken2, paramBoolean1, paramInt, paramBoolean2);
    CharLiteralElement localCharLiteralElement = new CharLiteralElement((LexerGrammar)this.grammar, paramToken1, paramBoolean1, paramInt);
    if ((!(((LexerGrammar)this.grammar).caseSensitive)) && (localCharLiteralElement.getType() < 128) && (Character.toLowerCase((char)localCharLiteralElement.getType()) != (char)localCharLiteralElement.getType()))
      this.tool.warning("Character literal must be lowercase when caseSensitive=false", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
    addElementToCurrentAlt(localCharLiteralElement);
    labelElement(localCharLiteralElement, paramToken2);
    String str = this.ruleBlock.getIgnoreRule();
    if ((!(paramBoolean2)) && (str != null))
      addElementToCurrentAlt(createOptionalRuleRef(str, paramToken1));
  }

  public void refCharRange(Token paramToken1, Token paramToken2, Token paramToken3, int paramInt, boolean paramBoolean)
  {
    if (!(this.grammar instanceof LexerGrammar))
    {
      this.tool.error("Character range only valid in lexer", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
      return;
    }
    int i = ANTLRLexer.tokenTypeForCharLiteral(paramToken1.getText());
    int j = ANTLRLexer.tokenTypeForCharLiteral(paramToken2.getText());
    if (j < i)
    {
      this.tool.error("Malformed range.", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
      return;
    }
    if (!(((LexerGrammar)this.grammar).caseSensitive))
    {
      if ((i < 128) && (Character.toLowerCase((char)i) != (char)i))
        this.tool.warning("Character literal must be lowercase when caseSensitive=false", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
      if ((j < 128) && (Character.toLowerCase((char)j) != (char)j))
        this.tool.warning("Character literal must be lowercase when caseSensitive=false", this.grammar.getFilename(), paramToken2.getLine(), paramToken2.getColumn());
    }
    super.refCharRange(paramToken1, paramToken2, paramToken3, paramInt, paramBoolean);
    CharRangeElement localCharRangeElement = new CharRangeElement((LexerGrammar)this.grammar, paramToken1, paramToken2, paramInt);
    addElementToCurrentAlt(localCharRangeElement);
    labelElement(localCharRangeElement, paramToken3);
    String str = this.ruleBlock.getIgnoreRule();
    if ((!(paramBoolean)) && (str != null))
      addElementToCurrentAlt(createOptionalRuleRef(str, paramToken1));
  }

  public void refTokensSpecElementOption(Token paramToken1, Token paramToken2, Token paramToken3)
  {
    TokenSymbol localTokenSymbol = this.grammar.tokenManager.getTokenSymbol(paramToken1.getText());
    if (localTokenSymbol == null)
      this.tool.panic("cannot find " + paramToken1.getText() + "in tokens {...}");
    if (paramToken2.getText().equals("AST"))
      localTokenSymbol.setASTNodeType(paramToken3.getText());
    else
      this.grammar.antlrTool.error("invalid tokens {...} element option:" + paramToken2.getText(), this.grammar.getFilename(), paramToken2.getLine(), paramToken2.getColumn());
  }

  public void refElementOption(Token paramToken1, Token paramToken2)
  {
    AlternativeElement localAlternativeElement = context().currentElement();
    if ((localAlternativeElement instanceof StringLiteralElement) || (localAlternativeElement instanceof TokenRefElement) || (localAlternativeElement instanceof WildcardElement))
      ((GrammarAtom)localAlternativeElement).setOption(paramToken1, paramToken2);
    else
      this.tool.error("cannot use element option (" + paramToken1.getText() + ") for this kind of element", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
  }

  public void refExceptionHandler(Token paramToken1, Token paramToken2)
  {
    super.refExceptionHandler(paramToken1, paramToken2);
    if (this.currentExceptionSpec == null)
      this.tool.panic("exception handler processing internal error");
    this.currentExceptionSpec.addHandler(new ExceptionHandler(paramToken1, paramToken2));
  }

  public void refInitAction(Token paramToken)
  {
    super.refAction(paramToken);
    context().block.setInitAction(paramToken.getText());
  }

  public void refMemberAction(Token paramToken)
  {
    this.grammar.classMemberAction = paramToken;
  }

  public void refPreambleAction(Token paramToken)
  {
    super.refPreambleAction(paramToken);
  }

  public void refReturnAction(Token paramToken)
  {
    if (this.grammar instanceof LexerGrammar)
    {
      String str = CodeGenerator.encodeLexerRuleName(((RuleBlock)context().block).getRuleName());
      RuleSymbol localRuleSymbol = (RuleSymbol)this.grammar.getSymbol(str);
      if (localRuleSymbol.access.equals("public"))
      {
        this.tool.warning("public Lexical rules cannot specify return type", this.grammar.getFilename(), paramToken.getLine(), paramToken.getColumn());
        return;
      }
    }
    ((RuleBlock)context().block).returnAction = paramToken.getText();
  }

  public void refRule(Token paramToken1, Token paramToken2, Token paramToken3, Token paramToken4, int paramInt)
  {
    if (this.grammar instanceof LexerGrammar)
    {
      if (paramToken2.type != 24)
      {
        this.tool.error("Parser rule " + paramToken2.getText() + " referenced in lexer");
        return;
      }
      if (paramInt == 2)
        this.tool.error("AST specification ^ not allowed in lexer", this.grammar.getFilename(), paramToken2.getLine(), paramToken2.getColumn());
    }
    super.refRule(paramToken1, paramToken2, paramToken3, paramToken4, paramInt);
    this.lastRuleRef = new RuleRefElement(this.grammar, paramToken2, paramInt);
    if (paramToken4 != null)
      this.lastRuleRef.setArgs(paramToken4.getText());
    if (paramToken1 != null)
      this.lastRuleRef.setIdAssign(paramToken1.getText());
    addElementToCurrentAlt(this.lastRuleRef);
    String str = paramToken2.getText();
    if (paramToken2.type == 24)
      str = CodeGenerator.encodeLexerRuleName(str);
    RuleSymbol localRuleSymbol = (RuleSymbol)this.grammar.getSymbol(str);
    localRuleSymbol.addReference(this.lastRuleRef);
    labelElement(this.lastRuleRef, paramToken3);
  }

  public void refSemPred(Token paramToken)
  {
    super.refSemPred(paramToken);
    if (context().currentAlt().atStart())
    {
      context().currentAlt().semPred = paramToken.getText();
    }
    else
    {
      ActionElement localActionElement = new ActionElement(this.grammar, paramToken);
      localActionElement.isSemPred = true;
      addElementToCurrentAlt(localActionElement);
    }
  }

  public void refStringLiteral(Token paramToken1, Token paramToken2, int paramInt, boolean paramBoolean)
  {
    int i;
    super.refStringLiteral(paramToken1, paramToken2, paramInt, paramBoolean);
    if ((this.grammar instanceof TreeWalkerGrammar) && (paramInt == 2))
      this.tool.error("^ not allowed in here for tree-walker", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
    StringLiteralElement localStringLiteralElement = new StringLiteralElement(this.grammar, paramToken1, paramInt);
    if ((this.grammar instanceof LexerGrammar) && (!(((LexerGrammar)this.grammar).caseSensitive)))
      for (i = 1; i < paramToken1.getText().length() - 1; ++i)
      {
        char c = paramToken1.getText().charAt(i);
        if ((c < 128) && (Character.toLowerCase(c) != c))
        {
          this.tool.warning("Characters of string literal must be lowercase when caseSensitive=false", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
          break;
        }
      }
    addElementToCurrentAlt(localStringLiteralElement);
    labelElement(localStringLiteralElement, paramToken2);
    String str = this.ruleBlock.getIgnoreRule();
    if ((!(paramBoolean)) && (str != null))
      addElementToCurrentAlt(createOptionalRuleRef(str, paramToken1));
  }

  public void refToken(Token paramToken1, Token paramToken2, Token paramToken3, Token paramToken4, boolean paramBoolean1, int paramInt, boolean paramBoolean2)
  {
    Object localObject;
    if (this.grammar instanceof LexerGrammar)
    {
      if (paramInt == 2)
        this.tool.error("AST specification ^ not allowed in lexer", this.grammar.getFilename(), paramToken2.getLine(), paramToken2.getColumn());
      if (paramBoolean1)
        this.tool.error("~TOKEN is not allowed in lexer", this.grammar.getFilename(), paramToken2.getLine(), paramToken2.getColumn());
      refRule(paramToken1, paramToken2, paramToken3, paramToken4, paramInt);
      localObject = this.ruleBlock.getIgnoreRule();
      if ((!(paramBoolean2)) && (localObject != null))
        addElementToCurrentAlt(createOptionalRuleRef((String)localObject, paramToken2));
    }
    else
    {
      if (paramToken1 != null)
        this.tool.error("Assignment from token reference only allowed in lexer", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
      if (paramToken4 != null)
        this.tool.error("Token reference arguments only allowed in lexer", this.grammar.getFilename(), paramToken4.getLine(), paramToken4.getColumn());
      super.refToken(paramToken1, paramToken2, paramToken3, paramToken4, paramBoolean1, paramInt, paramBoolean2);
      localObject = new TokenRefElement(this.grammar, paramToken2, paramBoolean1, paramInt);
      addElementToCurrentAlt((AlternativeElement)localObject);
      labelElement((AlternativeElement)localObject, paramToken3);
    }
  }

  public void refTokenRange(Token paramToken1, Token paramToken2, Token paramToken3, int paramInt, boolean paramBoolean)
  {
    if (this.grammar instanceof LexerGrammar)
    {
      this.tool.error("Token range not allowed in lexer", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
      return;
    }
    super.refTokenRange(paramToken1, paramToken2, paramToken3, paramInt, paramBoolean);
    TokenRangeElement localTokenRangeElement = new TokenRangeElement(this.grammar, paramToken1, paramToken2, paramInt);
    if (localTokenRangeElement.end < localTokenRangeElement.begin)
    {
      this.tool.error("Malformed range.", this.grammar.getFilename(), paramToken1.getLine(), paramToken1.getColumn());
      return;
    }
    addElementToCurrentAlt(localTokenRangeElement);
    labelElement(localTokenRangeElement, paramToken3);
  }

  public void refTreeSpecifier(Token paramToken)
  {
    context().currentAlt().treeSpecifier = paramToken;
  }

  public void refWildcard(Token paramToken1, Token paramToken2, int paramInt)
  {
    super.refWildcard(paramToken1, paramToken2, paramInt);
    WildcardElement localWildcardElement = new WildcardElement(this.grammar, paramToken1, paramInt);
    addElementToCurrentAlt(localWildcardElement);
    labelElement(localWildcardElement, paramToken2);
  }

  public void reset()
  {
    super.reset();
    this.blocks = new LList();
    this.lastRuleRef = null;
    this.ruleEnd = null;
    this.ruleBlock = null;
    this.nested = 0;
    this.currentExceptionSpec = null;
    this.grammarError = false;
  }

  public void setArgOfRuleRef(Token paramToken)
  {
    super.setArgOfRuleRef(paramToken);
    this.lastRuleRef.setArgs(paramToken.getText());
  }

  public static void setBlock(AlternativeBlock paramAlternativeBlock1, AlternativeBlock paramAlternativeBlock2)
  {
    paramAlternativeBlock1.setAlternatives(paramAlternativeBlock2.getAlternatives());
    paramAlternativeBlock1.initAction = paramAlternativeBlock2.initAction;
    paramAlternativeBlock1.label = paramAlternativeBlock2.label;
    paramAlternativeBlock1.hasASynPred = paramAlternativeBlock2.hasASynPred;
    paramAlternativeBlock1.hasAnAction = paramAlternativeBlock2.hasAnAction;
    paramAlternativeBlock1.warnWhenFollowAmbig = paramAlternativeBlock2.warnWhenFollowAmbig;
    paramAlternativeBlock1.generateAmbigWarnings = paramAlternativeBlock2.generateAmbigWarnings;
    paramAlternativeBlock1.line = paramAlternativeBlock2.line;
    paramAlternativeBlock1.greedy = paramAlternativeBlock2.greedy;
    paramAlternativeBlock1.greedySet = paramAlternativeBlock2.greedySet;
  }

  public void setRuleOption(Token paramToken1, Token paramToken2)
  {
    this.ruleBlock.setOption(paramToken1, paramToken2);
  }

  public void setSubruleOption(Token paramToken1, Token paramToken2)
  {
    context().block.setOption(paramToken1, paramToken2);
  }

  public void synPred()
  {
    if (context().block.not)
      this.tool.error("'~' cannot be applied to syntactic predicate", this.grammar.getFilename(), context().block.getLine(), context().block.getColumn());
    SynPredBlock localSynPredBlock = new SynPredBlock(this.grammar);
    setBlock(localSynPredBlock, context().block);
    BlockContext localBlockContext = (BlockContext)this.blocks.pop();
    this.blocks.push(new BlockContext());
    context().block = localSynPredBlock;
    context().blockEnd = localBlockContext.blockEnd;
    context().blockEnd.block = localSynPredBlock;
  }

  public void zeroOrMoreSubRule()
  {
    if (context().block.not)
      this.tool.error("'~' cannot be applied to (...)+ subrule", this.grammar.getFilename(), context().block.getLine(), context().block.getColumn());
    ZeroOrMoreBlock localZeroOrMoreBlock = new ZeroOrMoreBlock(this.grammar);
    setBlock(localZeroOrMoreBlock, context().block);
    BlockContext localBlockContext = (BlockContext)this.blocks.pop();
    this.blocks.push(new BlockContext());
    context().block = localZeroOrMoreBlock;
    context().blockEnd = localBlockContext.blockEnd;
    context().blockEnd.block = localZeroOrMoreBlock;
  }
}